package persistencia;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import dao.Hotel;
import dao.Lugar;
import dao.SeccionTransporte;
import dao.Terrestre;
import dao.Transporte;
import dao.Vuelo;

public class XMLPersistor extends Persistor {
	private static XMLPersistor instancia = null;
	private List<Lugar> lugares;
	private List<Transporte> transportes;
	private List<Hotel> hoteles;

	private XMLPersistor() {
		lugares = new ArrayList<Lugar>();
		transportes = new ArrayList<Transporte>();
		hoteles = new ArrayList<Hotel>();
	}

	public static XMLPersistor getInstancia() {
		if (instancia == null) {
			instancia = new XMLPersistor();
			instancia.cargarXML();
		}
		return instancia;
	}

	private Date getFecha(String fechaCadena) {
		SimpleDateFormat formatoDelTexto = new SimpleDateFormat("dd/MM/yyyy");
		Date fecha = null;
		try {
			fecha = formatoDelTexto.parse(fechaCadena);

		} catch (ParseException ex) {

			ex.printStackTrace();

		}
		return fecha;
	}

	private String getElemento(Element elemento, String campo) {
		return elemento.getElementsByTagName(campo).item(0).getTextContent();
	}

	private void cargarLugares(Document documento) {
		NodeList listaLugares = documento.getElementsByTagName("lugar");
		for (int idxLugar = 0; idxLugar < listaLugares.getLength(); idxLugar++) {
			Node nodo = listaLugares.item(idxLugar);
			if (nodo.getNodeType() == Node.ELEMENT_NODE) {
				Element elemento = (Element) nodo;
				Lugar lugar = new Lugar();
				lugar.setNombre(getElemento(elemento, "nombre"));
				lugar.setDescripcion(getElemento(elemento, "descripcion"));
				lugar.setUrl(getElemento(elemento, "url"));
				lugar.setMapa(getElemento(elemento, "mapa"));
				NodeList listaAtracciones = elemento
						.getElementsByTagName("atraccion");
				List<String> atracciones = new ArrayList<String>();
				for (int idxAtraccion = 0; idxAtraccion < listaAtracciones
						.getLength(); idxAtraccion++) {
					nodo = listaAtracciones.item(idxAtraccion);
					if (nodo.getNodeType() == Node.ELEMENT_NODE) {
						elemento = (Element) nodo;
						atracciones.add(elemento.getTextContent());
					}
				}
				lugar.setAtracciones(atracciones);
				lugares.add(lugar);
				System.out.println(lugar.toString());
			}
		}
	}
	
	private void cargarHoteles(Document documento) {
		NodeList listaHoteles = documento.getElementsByTagName("hotel");
		for (int idxHotel = 0; idxHotel < listaHoteles.getLength(); idxHotel++) {
			Node nodo = listaHoteles.item(idxHotel);
			if (nodo.getNodeType() == Node.ELEMENT_NODE) {
				Element elemento = (Element) nodo;
				Hotel hotel = new Hotel();
				hotel.setLugar(new Lugar(getElemento(elemento, "lugar")));
				hotel.setNombre(getElemento(elemento, "nombre"));
				hotel.setDireccion(getElemento(elemento, "direccion"));
				/*
				NodeList listaTipoHabitaciones = elemento
						.getElementsByTagName("tipoHabitacion");
				List<String> atracciones = new ArrayList<String>();
				for (int idxAtraccion = 0; idxAtraccion < listaTipoHabitaciones
						.getLength(); idxAtraccion++) {
					nodo = listaTipoHabitaciones.item(idxAtraccion);
					if (nodo.getNodeType() == Node.ELEMENT_NODE) {
						elemento = (Element) nodo;
						atracciones.add(elemento.getTextContent());
					}
				}
				*/
				//hotel.set(atracciones);
				hoteles.add(hotel);
				System.out.println(hotel.toString());
			}
		}
	}

	private void cargarTransportes(Document documento) {
		NodeList listaTransportes = documento.getElementsByTagName("transporte");
		Transporte transporte = null;
		for (int idxTransporte = 0; idxTransporte < listaTransportes
				.getLength(); idxTransporte++) {
			Node nodo = listaTransportes.item(idxTransporte);
			if (nodo.getNodeType() == Node.ELEMENT_NODE) {
				Element elemento = (Element) nodo;
				String tipoTransporte = getElemento(elemento, "tipo");
				if (tipoTransporte.equals("Avion")) {
					transporte = new Vuelo();
				} else if (tipoTransporte.equals("Camion")) {
					transporte = new Terrestre();
				}
				transporte.setTipoTransporte(tipoTransporte);
				transporte.setProveedor(getElemento(elemento, "proveedor"));
				transporte.setHorario(getElemento(elemento, "horario"));
				transporte.setFecha(getFecha(getElemento(elemento, "fecha")));
				transporte
						.setOrigen(new Lugar(getElemento(elemento, "origen")));
				transporte.setDestino(new Lugar(
						getElemento(elemento, "destino")));
				transporte.setIdentificador(getElemento(elemento,
						"identificador"));
				NodeList listaSecciones = elemento
						.getElementsByTagName("seccion");
				List<SeccionTransporte> secciones = new ArrayList<SeccionTransporte>();
				for (int idxSeccion = 0; idxSeccion < listaSecciones
						.getLength(); idxSeccion++) {
					nodo = listaSecciones.item(idxSeccion);
					elemento = (Element) nodo;
					SeccionTransporte seccionTransporte = new SeccionTransporte();
					seccionTransporte.setClase(getElemento(elemento, "clase"));
					seccionTransporte.setCosto(Float.parseFloat(getElemento(
							elemento, "costo")));
					seccionTransporte.setDescripcion(getElemento(elemento,
							"descripcion"));
					secciones.add(seccionTransporte);
				}
				transporte.setSecciones(secciones);
				transportes.add(transporte);
				System.out.println(transporte.toString());
			}
		}
	}

	private void cargarXML() {
		try {
			File archivoXML = new File("catalogos.xml");
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document documento = dBuilder.parse(archivoXML);
			documento.getDocumentElement().normalize();
			cargarLugares(documento);
			cargarHoteles(documento);
			cargarTransportes(documento);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public List<Lugar> getLugares() {
		return lugares;
	}

	@Override
	public List<Hotel> getHoteles() {
		return hoteles;
	}

	@Override
	public List<Transporte> getTransportes() {
		return null;
	}
}
